﻿using System.Collections.Generic;
using System.Windows;
using Microsoft.Shell;
using JiveMessenger.Views;
using JiveMessenger;
using System.ComponentModel;
using System.Configuration;
using System;
using System.IO;
using JmShared;
using System.Threading;
using NLog.Config;
using NLog.Targets;
using NLog;
using JiveMessenger.NotifyWindow;
using GalaSoft.MvvmLight.Messaging;
//using JiveMessenger.ViewModels;
using JiveMessenger.Utilities;
using System.Windows.Markup;
using System.Globalization;
using System.Windows.Threading;
using JiveMessenger.ViewModels;
using System.Net;
using JiveMessenger.Misc;
using System.Reflection;
using System.Threading.Tasks;

namespace JiveMessenger
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application, ISingleInstanceApp
    {
        private const string Unique = "JiveMessengerV2";
        //  public static Client CurrentClient;
        static App()
        {
#if DEBUG

#else
            // This supports single-instance behavior
            if (Microsoft.Shell.SingleInstance<App>.InitializeAsFirstInstance(Unique))
            {
                var application = new App();
                application.InitializeComponent();
                application.Run();
                // Allow single instance code to perform cleanup operations
                Microsoft.Shell.SingleInstance<App>.Cleanup();
                application.Shutdown();
            }

            // Now kill this process or it will try to run the shutdown
            // single instance or try to run the instance that should have
            // been swallowed up.
            System.Diagnostics.Process.GetCurrentProcess().Kill();
#endif
        }
        public App()
        {

            InitLogging();
            FrameworkElement.LanguageProperty.OverrideMetadata(
      typeof(FrameworkElement),
      new FrameworkPropertyMetadata(
          XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));

            if (JiveMessenger.Properties.Settings.Default.UpdateSettings)
            {

                JiveMessenger.Properties.Settings.Default.Upgrade();
                JiveMessenger.Properties.Settings.Default.UpdateSettings = false;
                JiveMessenger.Properties.Settings.Default.Save();
                ProgramSettings.Instance.JustUpdated = true;


            }
            ProgramSettings.Instance.ContactListState = StaticMethods.StringToObject<Dictionary<string, ContactListState>>(JiveMessenger.Properties.Settings.Default.SettingStoredChatContactListState);
            JiveMessenger.Properties.Settings.Default.SettingChanging += Default_SettingChanging;
            JiveMessenger.Properties.Settings.Default.PropertyChanged += Default_PropertyChanged;

            WebRequest.DefaultWebProxy = null;
        }



        protected override void OnExit(ExitEventArgs e)
        {
            base.OnExit(e);
        }

        private void Default_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "SettingShowOfflineContacts":
                    {
                        Messenger.Default.Send(new NotificationMessage(this, "RefreshContactsFilter"));
                        break;
                    }
            }
        }

        private void Default_SettingChanging(object sender, SettingChangingEventArgs e)
        {
            switch (e.SettingName)
            {
                case "SettingStartWithWindows":
                    {
                        bool newValue = (bool)e.NewValue;
                        if (newValue != JiveMessenger.Properties.Settings.Default.SettingStartWithWindows)
                        {
                            if (newValue)
                            {
                                var startup = Environment.GetFolderPath(Environment.SpecialFolder.CommonStartup);
                                string file = Path.Combine(startup, "JiveMessenger.lnk");
                                IWshRuntimeLibrary.WshShellClass shell = new IWshRuntimeLibrary.WshShellClass();
                                IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(file);
                                shortcut.TargetPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
                                shortcut.Description = "Jive Messenger ";
                                shortcut.IconLocation = System.Reflection.Assembly.GetExecutingAssembly().Location;
                                shortcut.Save();
                            }
                            else
                            {
                                var file = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonStartup), "JiveMessenger.lnk");
                                if (File.Exists(file))
                                {
                                    File.Delete(file);
                                }
                            }
                        }
                        break;
                    }
                case "SettingEnableDebugLogging":
                    {
                        bool newvalue = (bool)e.NewValue;
                        if (newvalue)
                            InitLogging();
                        else
                            LogManager.DisableLogging();
                        break;
                    }
                case "SettingEnableHoverImage":
                    {
                        if ((bool)e.NewValue == true)
                            Messenger.Default.Send(new NotificationMessage(this, "StartImagePreview"));
                        else
                            Messenger.Default.Send(new NotificationMessage(this, "StopImagePreview"));
                        break;
                    }
            }
        }
        
        /// <summary>
        /// Initialize logging
        /// </summary>
        public static void InitLogging()
        {
            string userLogDir = ProgramSettings.Instance.ErrorLogFolder;
            if (!Directory.Exists(userLogDir))
                Directory.CreateDirectory(userLogDir);

            LoggingConfiguration logConfig = new LoggingConfiguration();

           // string userLogDir = Environment.UserName.Replace(" ", "");
            using (DebuggerTarget debugTarget = new DebuggerTarget())
            {

                using (FileTarget fileTarget = new FileTarget
                {

                   // FileName = "${basedir}/" + userLogDir + "/log.txt",
                   FileName=userLogDir+"/log.txt",
                    Layout = "${date:format=dd-MMM-yyyy HH\\:mm\\:ss} [${level}] - ${callsite:fileName=true} - ${message}  ${exception:format=tostring}${newline} --------------------------------------------------",
                    ArchiveAboveSize = 1048576,
                    ArchiveNumbering = ArchiveNumberingMode.Rolling,
                   // ArchiveFileName = "${basedir}/" + userLogDir + "/archive/log.{#####}.txt",
                   ArchiveFileName = userLogDir + "/archive/log.{#####}.txt",
                    MaxArchiveFiles = 4
                })
                {
                    logConfig.AddTarget("file", fileTarget);
                    logConfig.AddTarget("debug", debugTarget);

                    LogLevel l = null;
                    switch (JiveMessenger.Properties.Settings.Default.SettingDebugLogLevel)
                    {
                        case "Fatal":
                            l = LogLevel.Fatal;
                            break;
                        case "Error":
                            l = LogLevel.Error;
                            break;
                        case "Warn":
                            l = LogLevel.Warn;
                            break;
                        case "Info":
                            l = LogLevel.Info;
                            break;
                        case "Debug":
                            l = LogLevel.Debug;
                            break;
                        case "Trace":
                            l = LogLevel.Trace;
                            break;
                    }
                    if (!JiveMessenger.Properties.Settings.Default.SettingEnableDebugLogging)
                        l = LogLevel.Off;
                    if (l == null)
                        return;
                    logConfig.LoggingRules.Add(new LoggingRule("*", l, fileTarget));
                    logConfig.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, debugTarget));

                    LogManager.Configuration = logConfig;
                    LogManager.EnableLogging();
                }
            }
        }
        //[STAThread]
        //public static void Main()
        //{
        //    if (SingleInstance<App>.InitializeAsFirstInstance(Unique))
        //    {
        //        var application = new App();

        //        application.InitializeComponent();
        //        application.Run();

        //        // Allow single instance code to perform cleanup operations
        //        SingleInstance<App>.Cleanup();
        //    }
        //}
        #region ISingleInstanceApp Members

        public bool SignalExternalCommandLineArgs(IList<string> args)
        {
            // handle command line arguments of second instance
            // ...
            //  Application.Current.MainWindow.Focus();

            Application.Current.MainWindow.Activate();
            if (Application.Current.MainWindow.WindowState == WindowState.Minimized)
                Application.Current.MainWindow.WindowState = WindowState.Normal;
            return ProcessCommandLineArgs(args);
            //return true;
        }

        #endregion
        public bool ProcessCommandLineArgs(IList<string> args)
        {
            if (args == null || args.Count == 0)
                return true;


            if ((args.Count > 1))
            {
                //the first index always contains the location of the exe so we need to check the second index
                if ((args[1].ToLowerInvariant() == "/hello"))
                {
                    MessageBox.Show("Hello World");
                }
                else if ((args[1].ToLowerInvariant() == "/goodbye"))
                {
                    MessageBox.Show("Goodbye cruel world");
                }
            }

            return true;
        }

        void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs args)
        {
#if DEBUG

#else
                        Logger l = LogManager.GetCurrentClassLogger();
            l.FatalException("An unexpected application exception occurred", args.Exception);

            MessageBox.Show("An unexpected exception has occurred. Shutting down the application. Please check the log file for more details.");

            // Prevent default unhandled exception processing
            args.Handled = true;

            Environment.Exit(0);
#endif

        }

        private void Application_Activated(object sender, EventArgs e)
        {
            //var locator = (ViewModelLocator)Application.Current.Resources["Locator"];
            //MainWindow.DataContext = locator.ViewModelMainWindow;
        }
    }
}
